Miyamasuを支える技術というかUnityEditorロックインな知識


概要

Miyamasuを作った時に発覚したいろんな新常識を列挙していく。


Miyamasu

https://github.com/sassembla/Miyamasu



PlayerのTheadとUnityEditor.EditorApplication.updateの話


Unityの制作環境には大きく2つ、MainThreadへのアクセスポイントがあり、

1つはPlayerが動いているときのUpdateとかあのへん。MonoBehaviourが動いているContext。


もう一つは、UnityEditor.EditorApplication.updateが動いているContext。



この2つのContextは、根本的には一つのThread(= MainThread)にアクセスしていて、その動作に差異は「ほぼ」ない。


具体例として、

UnityのMainThreadでしか動かないよ~的なメソッドは、そのほぼ全てが UnityEditor.EditorApplication.update でも動かすことができる。



Play中でないと絶対に動かない処理がある

UnityEditor.EditorApplication.update と、MonoBehaviourは等価っぽい、、、のだけれど、


次のメソッドは、Play中でないと動作が完了しないことがわかっている。

・LoadAssetAsync

・ConfigurationBuilder.Instance

LoadAssetAsync

DLしたAssetBundleを非同期で読み出す処理なんだけど、全然完了しない。


ConfigurationBuilder.Instance

課金機構の設定用のインスタンスを返す処理なんだけど、これまた全然完了しない。


これらは、UnityEditorがIsPlaying = trueでないと動作しない。

が、


裏を返せば、UnityEditorがIsPlaying = true でさえあれば、

例えば、UnityEditor.EditorApplication.updateからでも動作する。


考察としては、

・これらのメソッド中には、Play中かどうかをみて動くような処理が実装されている

という感じ。


もしくはバグ。だってUnityWebRequestとか同期版のLoadAssetは動く。

この2つのメソッド以外にもあるかも。(特に探せてない


ちなみに実機上でテストを動かす場合には全然問題ない。



なぜNUnitを使わないかについて、、、うん、、、、

Unity、NUnitを使ってテストを書くことができるんだけど、テスト実行単位で一つのMainThreadだけが動く状態で、

MainThread主体のコンテキストで動いてしまい、MainThreadを空転させるような動作ができない。


もうちょっというと、例えばStartCoroutineして、その処理の終了を待つ、みたいなことができない。


MainThreadで動いてて、MainThreadで動かすような処理を待ちたい、で、待つ = ロックしちゃう = 非同期で完了を待ちたい処理もロックしちゃう。


ので、非同期的な処理を待つことができない。


ので、非同期テストができない。


ご丁寧なことに、NUnit中には、上記のUnityEditor.updateも動かない。

はい解散。